package com.example.validatestudy.demos.tread.deadlock;

import lombok.AllArgsConstructor;
import lombok.Data;

import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @auther: 王振方
 * @date: 2024 05 06 14 25
 * @description:
 */
public class BreakDeadLockTest01 {
    public static void main(String[] args) {
        /**
         * 避免死锁，不使用synchronized
         */
        breakDeadLockTest();
    }

    public static void breakDeadLockTest(){
        Account zhangsan = new Account("张三",new AtomicInteger(100));
        Account lisi = new Account("李四",new AtomicInteger(100));

        ThreadPoolExecutor executor = new ThreadPoolExecutor(5,Integer.MAX_VALUE,60, TimeUnit.SECONDS
                ,new LinkedBlockingQueue<>(), Executors.defaultThreadFactory(),new ThreadPoolExecutor.DiscardOldestPolicy());
        executor.execute(()->zhangsan.transfer(lisi,100));
        executor.execute(()-> lisi.transfer(zhangsan ,100));
        executor.shutdown();
    }

    @AllArgsConstructor
    @Data
    static class Account {
        private String name;
        private AtomicInteger atomicBalance;

        void transfer(Account to, Integer num){
            try {
                synchronized (this) {
                    if (this.getAtomicBalance().get() >= num && this.getAtomicBalance().get()>0) {
                        this.getAtomicBalance().addAndGet(-num);
                        System.out.println(Thread.currentThread().getName()+"扣款完成，"+this.getName()+"余额："+this.getAtomicBalance().get());
                        Thread.sleep(1000);
                        to.getAtomicBalance().addAndGet(num);
                        System.out.println(Thread.currentThread().getName() + "转账完成，" + to.getName() + "余额：" + to.getAtomicBalance().get());
                    }
                }
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
    }
}

